/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: LambdaTest
 * Author:   zhouheng
 * Date:     2019/4/4 22:43
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */

import pojo.Employee;

import java.util.*;

/**
 * 〈一句话功能简述〉<br> 
 * 〈lambda test〉
 *
 * @author zhouheng
 * @create 2019/4/4
 * @since 1.0.0
 */
public class LambdaTest {

    public static void main(String[] args) {
        // 内部类
        Comparator<String> com = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.compare(Integer.parseInt(o1), Integer.parseInt(o2));
            }
        };

        TreeSet<String> ts = new TreeSet<>(com);
        ts.add("6");
        ts.add("2");
        ts.add("4");
        ts.add("3");

        Iterator<String> iterator = ts.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        // lambda表达式写法
        Comparator<String> com1 = (x, y) -> Integer.compare(Integer.parseInt(x), Integer.parseInt(y));
        TreeSet<String> ts1 = new TreeSet<>(com);
        ts1.add("7");
        ts1.add("6");
        ts1.add("4");
        ts1.add("3");

        Iterator<String> iterator1 = ts1.iterator();
        while (iterator1.hasNext()) {
            System.out.println(iterator1.next());
        }

        List<Employee> employeeList = Arrays.asList(
                new Employee("1", "zhangsan", 5000d, 20, Employee.Status.BUSY),
                new Employee("2", "lisi", 4000d, 40,Employee.Status.BUSY),
                new Employee("3", "wangwu", 3000d, 30,Employee.Status.BUSY),
                new Employee("4", "zhaoliu", 6000d, 50,Employee.Status.BUSY));
        // 需求：获取公司中年龄小于 35 的员工信息
        List<Employee> employeesList = filterEmployeeAge(employeeList);
        Iterator<Employee> iterator2 = employeesList.iterator();
        while (iterator2.hasNext()) {
            System.out.println(iterator2.next().toString());
        }

        System.out.println();
        //需求：获取公司中工资大于 5000 的员工信息
        employeesList = filterEmployeeBySalary(employeeList);
        iterator2 = employeesList.iterator();
        while (iterator2.hasNext()) {
            System.out.println(iterator2.next().toString());
        }

        System.out.println("------------------------------------------");

        // 优化方案3 策略模式 以类的形式 不足之处 类会增加很多 每增加一个策略 需添加一个类实现策略接口
        List<Employee> list = filterEmployee(employeeList, new FilterEmployeeForAge());
        for (Employee employee : list) {
            System.out.println(employee);
        }

        System.out.println("------------------------------------------");

        List<Employee> list2 = filterEmployee(employeeList, new FilterEmployeeForSalary());
        for (Employee employee : list2) {
            System.out.println(employee);
        }

        System.out.println("--------------优化方案4之匿名内部类 策略模式-----------");
        // 优化方案4之匿名内部类 策略模式
        List<Employee> employees = filterEmployee(employeeList, new MyPredicate<Employee>() {
            @Override
            public boolean handle(Employee employee) {
                return employee.getAge() < 35;
            }
        });
        for (Employee employee : employees) {
            System.out.println(employee);
        }

        // 优化方案5 lambda表达式
        System.out.println("--------------优化方案5之lambda表达式 策略模式-----------");
        List<Employee> lambdaEmployees = filterEmployee(employeeList,(x) -> {return  x.getAge() < 35;});
        for (Employee employee : lambdaEmployees) {
            System.out.println(employee);
        }

        // 优化6 stream Api
        System.out.println("--------------优化方案6之stream api 策略模式-----------");
        employeeList.stream().filter((employee -> employee.getAge() < 30))
                            .forEach(System.out::println);
    }

    private static List<Employee>  filterEmployeeAge(List<Employee> employeeList) {

        List<Employee> list = new ArrayList<>();

        for (Employee emp : employeeList) {
            if(emp.getAge() <= 35){
                list.add(emp);
            }
        }

        return list;
    }

    private static List<Employee>  filterEmployeeBySalary(List<Employee> employeeList) {

        List<Employee> list = new ArrayList<>();

        for (Employee emp : employeeList) {
            if(emp.getSalary() <= 4000){
                list.add(emp);
            }
        }

        return list;
    }

    public static List<Employee> filterEmployee(List<Employee> emps, MyPredicate<Employee> mp){
        List<Employee> list = new ArrayList<>();

        for (Employee employee : emps) {
            if(mp.handle(employee)){
                list.add(employee);
            }
        }

        return list;
    }
}